/**
 * WechatController.java created by zhangzhidong 
 * at 下午12:52:09 2016年8月2日
 */
package controllers.wechatlab;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.lab.libsvm.driver.svm_predict;
import org.shirdrn.document.preprocessing.api.Term;
import org.shirdrn.document.preprocessing.api.constants.ConfigKeys;
import org.shirdrn.document.preprocessing.driver.TestDocumentPreprocessingDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;

import pojo.ResCode;
import thirdpart.wechat.rmi.WechatInterface;
import websocket.WebSocketCenter;
import websocket.WechatModelWebSocketHandler;
import websocket.interceptor.HandshakeInterceptor;

/**
 * @author zhangzhidong<br>
 *         comment generated at 2016年8月2日下午12:52:09<br>
 */
@Controller
@RequestMapping("wexp")
public class WechatController extends TextProcessingController implements org.springframework.web.socket.server.HandshakeInterceptor{
	
	@Autowired
	@Qualifier("clientWechatService")
	WechatInterface rmiWechatService;
	WechatModelWebSocketHandler ws;
	/**
	 * 注册,做为Handshanke的回调
	 */
	public WechatController() {
		WebSocketCenter.registerListener(this);
	}
	@Autowired
	public void setWechatModelWebSocketHandler(WechatModelWebSocketHandler ws) {
		this.ws = ws;
		this.ws.setController(this);
	}
	@RequestMapping("/classify.do")
	@ResponseBody
	public String classify(HttpServletRequest req, HttpServletResponse res) throws IOException {
		req.setCharacterEncoding("UTF-8");
		String srcText[] = req.getParameterValues("srcText");
		if (srcText == null || srcText.length == 0) {
			return jsonDump(ParamsError);
		} else {
			//将数据写入到文件
			ff(srcText,req);
			String uid = getUserDirectory(req);
			Properties p = (Properties) getApplicationPropertis().clone();
			String []keys = {ConfigKeys.DATASET_TEST_INPUT_ROOT_FILE};
			for(String key:keys){
				String path = p.getProperty(key);
				File f = new File(path,uid);
				p.setProperty(key, f.getAbsolutePath());
			}	
			//将ff函数写入到文件中的文本预处理成为向量,输出的目录是new File(ConfigKeys.DATASET_TEST_SVM_VECTOR_OUTPUT_DIR,ConfigKeys.DATASET_TEST_SVM_VECTOR_FILE)
			TestDocumentPreprocessingDriver.startProc(uid, null, p);
			//调用svm进行分类
			//输出文件名
			String dir = p.getProperty(ConfigKeys.DATASET_TEST_SVM_VECTOR_OUTPUT_DIR);
			String filename =p.getProperty(ConfigKeys.DATASET_TEST_SVM_VECTOR_FILE);
			//f是向量化后的文件
			File f = new File(new File(dir,uid),filename);
			//model 路径
			String trainfiledir = (String) p.get(ConfigKeys.DATASET_TRAIN_SVM_VECTOR_OUTPUT_DIR);
			String model=trainfiledir+uid+System.getProperty("file.separator")+MODEL;
			//model的输出路径
			File output = new File(new File(dir,uid),"classify.txt");
			String argv[] = {f.getAbsolutePath(),model,output.getAbsolutePath()};
			svm_predict.main(argv);
			try(BufferedReader br = new BufferedReader(new FileReader(output))){
				String content = br.readLine();
				return content;
			}
		}
	}
	private void ff(String []wcs,HttpServletRequest req) throws IOException{
		Properties p =  getApplicationPropertis();
		String filename = "received.txt";
		File f = new File(p.getProperty(ConfigKeys.DATASET_TEST_INPUT_ROOT_FILE),getUserDirectory(req));
		f = new File(f,"c1");
		if(!f.exists()){
			f.mkdirs();
		}
		File savedFile = new File(f,filename);
		if(!savedFile.exists()){
			savedFile.createNewFile();
		}
		try(FileWriter fw = new FileWriter(savedFile,false)){
			for(String wc : wcs){
				fw.write(wc);
				fw.write(System.getProperty("line.separator"));
			}
		}
	}
	@RequestMapping("/fil.do")
	@ResponseBody
	public String filterNoise(HttpServletRequest req, HttpServletResponse res) {
		String srcText = req.getParameter("srcText");
		String filtered = rmiWechatService.filterNoise(srcText);
		if (srcText == null || srcText.length() == 0) {
			return jsonDump(ParamsError);
		} else {
			return jsonDump(new ResCode(200, filtered));
		}
	}
	@RequestMapping("/seg.do")
	@ResponseBody
	public String segment(HttpServletRequest req, HttpServletResponse res) {
		String srcText = req.getParameter("srcText");
		Map<String, Term> map = rmiWechatService.segment(srcText);
		return jsonDump(map);

	}

	@RequestMapping("/index.do")
	public ModelAndView expIndex(HttpServletRequest req, HttpServletResponse res) {
		System.out.println(Thread.currentThread());
		return renderView("wechatexp", null);
	}
	@RequestMapping("/indexB.do")
	public ModelAndView expIndexB(HttpServletRequest req, HttpServletResponse res) {
		return renderView("index0810", null);
	}

	@RequestMapping("/showTrain.do")
	public void apiShowTrain(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try{
			showTrain(req, res);
		}catch (Exception e){
			handleException(res, e);
		}
	}

	@RequestMapping("/showTrainCLass.do")
	public void apiShowTrainClass(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showTrainClass(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
	}

	@RequestMapping("/showTrainTerms.do")
	public void apiShowTrainTerms(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showTrainTerms(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
	}

	@RequestMapping("/showTrainFile.do")
	public void apiShowTrainFile(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showTrainFile(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
	}
	@RequestMapping("/trainModel.do")
	public void apiTrainModel(HttpServletRequest req, HttpServletResponse res) throws IOException{
		res.getWriter().println("not implement yet");
	}
	
//////////////////////////////////////////train libsvm 
	@RequestMapping("/showTrainScaleFile.do")
	public void apishowTrainScaleFile(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showTrainScaleFile(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
	}
	
	@RequestMapping("/showModelFile.do")
	public void apishowModelFile(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showModelFile(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
		
	}
	
	@RequestMapping("/showPredictResult.do")
	public void apishowPredictResult(HttpServletRequest req, HttpServletResponse res) throws IOException {
		try {
			showPredictResult(req, res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			handleException(res, e);
		}
	}
	////////////////////////////////
	public void sendMessageMessage(WebSocketSession session, String info) throws IOException, InterruptedException {

	}
	Map<String, WebSocketSession> users = new java.util.concurrent.ConcurrentHashMap<String, WebSocketSession>();
	
	public void establishWebSocket(final WebSocketSession session) throws IOException, InterruptedException {
		users.put(getUserDirectory(session), session);
	}
	public void closeWebSocket(WebSocketSession session, org.springframework.web.socket.CloseStatus status)
			throws IOException {
		System.out.println(session.toString() + " close received with a close status: " + status.getCode()
				+ " reasong: " + status.getReason());
		users.remove(getUserDirectory(session));
		session.close();
	}
	public void receiveMessageFromWebSocket(final WebSocketSession session, TextMessage message) {
		System.out.println(message + " from " + session);
		//收到一个用户的请求之后,新开一个线程,针对一个websocket连接处理数据,返回结果,因为数据分析所用的时候不定,不能一直阻塞服务器
		if (message.getPayload().equals("TRAIN")){
			exec.execute(new Runnable() {
				{
					this.s = session;
					this.uid = getUserDirectory(session);
				}
				String uid;
				WebSocketSession s;
				public void run() {
					try {
						s.sendMessage(new TextMessage("服务器已经收到请求,正在处理您的请求..."));
						WechatController.this.trainDoc(this.uid, this.s);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			});
			
		}else if (message.getPayload().equals("TEST")){
			//交叠验证进行的逻辑,这个需要将目录改了
			exec.execute(new Runnable() {
				{
					this.s = session;
					this.uid = getUserDirectory(session);
				}

				String uid;
				WebSocketSession s;
				public void run() {
					try {
						s.sendMessage(new TextMessage("服务器已经收到请求,正在处理您的请求..."));
						WechatController.this.testDoc(this.uid, this.s);
					
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	private void handleException(HttpServletResponse res,Exception e) throws IOException{
		res.getWriter().println(e.getMessage());
	}
	protected Executor exec = Executors.newFixedThreadPool(20);

	
	//以下两个方法目前没用,以后对于判断用户登陆才有用
	@Override
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Exception exception) {
		
	}
	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Map<String, Object> attributes) throws Exception {
		// TODO Auto-generated method stub
//		wsHandler.
		
		System.out.println(Thread.currentThread());
		System.out.println(((ServletServerHttpRequest)request).getServletRequest().getSession().getId());
		return true;
	}
}
